package com.springboot.jdk.nio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * FileChannel Demo 案例
 *
 * @author: zr
 * @date: 2021-10-19
 */
public class FileChannelDemo {

    public static void main(String[] args) throws IOException {
        String path = "F:\\develop\\channel\\hello.txt";

        File file = new File(path);
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        file.createNewFile();

        // 构造一个传统的文件输出流
        FileOutputStream fileOutputStream = new FileOutputStream(path);

        // 通过文件输出流获取到对应的FileChannel, 已NIO的方式来写文件
        FileChannel channel = fileOutputStream.getChannel();

        // 构建一个 ByteBuffer 缓冲区
        ByteBuffer wrap = ByteBuffer.wrap("hello world".getBytes());

        // 通过channel将 Buffer 里面的数据写入到磁盘文件里面
        channel.write(wrap);

        // channel 必须会从buffer 的 position= 0 的位置开始读起，一直读到limit， limit = 字符串直接数组的长度
        // buffer 的 position 是不是就是跟limit一样了
        System.out.println(wrap.position());
        // channel.position, 表示写到了文件的位置
        System.out.println(channel.position());
        // 继续往磁盘文件里面写，就是通过FileChannel的 position = 11 开始写，相当于末尾追加

        // 【顺序写】
        // 如果想再次将buffer里的数据通过channel 写入磁盘文件
        // rewind, position = 0, limit 保持不变
        wrap.rewind();
        System.out.println(wrap.position());
        System.out.println(channel.position());
        // 此时再次写一遍，文件中的数据就变成了 hello worldhello world
        // 在文件末尾追加写的方式，称之为顺序写
        // channel.write(wrap);

        // 【随机写】
        // 在hello 和 world 中间那个空格的地方，再写入一条数据 ,想变成 hello hello world
        // 把一段数据写入到磁盘文件的中间，磁盘随机
        // 把文件的随机位置写入数据
        // 肯定是要再次从buffer中读取数据，必须position必须复位

        // 通过调整channel的位置，要求从文件中的hello末尾开始写，又写了一份数据，就实现了文件的随机写
        // 默认是不停在文件追加，顺序写
        // 如果要实现随机写，可以通过调整channel的位置，在指定位置写数据数据
        // channel 也是有position概念的，默认情况下，是通过文件顺序写，不断在文件末尾添加数据；
        // 但是我们可以通过调整channel的position，实现随机写的功能
        channel.position(5);
        channel.write(wrap);

        channel.close();
        fileOutputStream.close();
    }
}
